#include <opencv2/opencv.hpp>
#include <filesystem>
#include <iostream>
#include <thread>
#include <mutex>
#include <deque>
#include <atomic>

namespace fs = std::filesystem;

// 判断是否为数字
bool is_number(const std::string &s)
{
    return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}

// 生成时间戳字符串
static std::string timestamp_string()
{
    auto now = std::chrono::system_clock::now();
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
    std::time_t t = std::chrono::system_clock::to_time_t(now);
    std::tm tm{};
    localtime_r(&t, &tm);
    char buf[64];
    snprintf(buf, sizeof(buf), "%04d%02d%02d_%02d%02d%02d_%03lld",
             tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
             tm.tm_hour, tm.tm_min, tm.tm_sec,
             (long long)ms.count());
    return buf;
}

int main(int argc, char **argv)
{
    std::string srcLeft = "31", srcRight = "22";
    if (argc >= 3)
    {
        srcLeft = argv[1];
        srcRight = argv[2];
    }

    cv::VideoCapture capLeft, capRight;
    if (is_number(srcLeft))
        capLeft.open(std::stoi(srcLeft));
    else
        capLeft.open(srcLeft);
    if (is_number(srcRight))
        capRight.open(std::stoi(srcRight));
    else
        capRight.open(srcRight);

    if (!capLeft.isOpened() || !capRight.isOpened())
    {
        std::cerr << "❌ 无法打开视频源\n";
        return -1;
    }

    // ⚙️ 尝试设置高清分辨率（如果支持）
    capLeft.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
    capLeft.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
    capRight.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
    capRight.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);

    // 读取实际生效的分辨率
    int leftW = static_cast<int>(capLeft.get(cv::CAP_PROP_FRAME_WIDTH));
    int leftH = static_cast<int>(capLeft.get(cv::CAP_PROP_FRAME_HEIGHT));
    int rightW = static_cast<int>(capRight.get(cv::CAP_PROP_FRAME_WIDTH));
    int rightH = static_cast<int>(capRight.get(cv::CAP_PROP_FRAME_HEIGHT));

    printf("左路实际分辨率: %dx%d\n", leftW, leftH);
    printf("右路实际分辨率: %dx%d\n", rightW, rightH);

    // 🖥️ 屏幕分辨率（获取失败则使用默认）
    int screenW = 0, screenH = 0;
#ifdef __linux__
    const char *cmd = "xdpyinfo | grep 'dimensions:' | awk '{print $2}'";
    FILE *pipe = popen(cmd, "r");
    if (pipe)
    {
        char buf[64];
        if (fgets(buf, sizeof(buf), pipe))
            sscanf(buf, "%dx%d", &screenW, &screenH);
        pclose(pipe);
    }
#endif
    if (screenW == 0 || screenH == 0)
    {
        screenW = 1920;
        screenH = 1080;
        printf("⚠️ 无法获取屏幕分辨率，使用默认值 %dx%d\n", screenW, screenH);
    }
    printf("屏幕分辨率: %dx%d\n", screenW, screenH);

    // 显示窗口大小 = 屏幕的 1/4（宽/2，高/2）
    int dispW = screenW / 2;
    int dispH = screenH / 2;
    printf("显示窗口大小: %dx%d\n", dispW, dispH);

    fs::path dirLeft = "images/left";
    fs::path dirRight = "images/right";
    fs::create_directories(dirLeft);
    fs::create_directories(dirRight);

    cv::namedWindow("LeftCamera", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("RightCamera", cv::WINDOW_AUTOSIZE);
    cv::moveWindow("LeftCamera", 0, 0);
    cv::moveWindow("RightCamera", dispW + 50, 0);

    std::cout << "按 's' 抓拍原始分辨率帧，'q' 退出\n";

    std::mutex mtxL, mtxR;
    std::deque<cv::Mat> queueL, queueR;
    std::atomic<bool> running(true);

    // 捕获线程函数
    auto capture_thread = [&](cv::VideoCapture &cap, std::deque<cv::Mat> &queue, std::mutex &mtx)
    {
        cv::Mat frame;
        while (running)
        {
            if (!cap.read(frame))
                continue;
            std::lock_guard<std::mutex> lock(mtx);
            queue.push_back(frame.clone());
            if (queue.size() > 5)
                queue.pop_front();
        }
    };

    std::thread tL(capture_thread, std::ref(capLeft), std::ref(queueL), std::ref(mtxL));
    std::thread tR(capture_thread, std::ref(capRight), std::ref(queueR), std::ref(mtxR));

    while (true)
    {
        cv::Mat rawL, rawR;
        {
            std::lock_guard<std::mutex> lk(mtxL);
            if (!queueL.empty()) rawL = queueL.back().clone();
        }
        {
            std::lock_guard<std::mutex> lk(mtxR);
            if (!queueR.empty()) rawR = queueR.back().clone();
        }

        // 显示缩放画面
        if (!rawL.empty())
        {
            cv::Mat showL;
            cv::resize(rawL, showL, cv::Size(dispW, dispH));
            cv::imshow("LeftCamera", showL);
        }
        if (!rawR.empty())
        {
            cv::Mat showR;
            cv::resize(rawR, showR, cv::Size(dispW, dispH));
            cv::imshow("RightCamera", showR);
        }

        int key = cv::waitKey(1);
        if (key == 's' || key == 'S')
        {
            if (!rawL.empty() && !rawR.empty())
            {
                std::string ts = timestamp_string();
                fs::path fileL = dirLeft / (ts + ".jpg");
                fs::path fileR = dirRight / (ts + ".jpg");

                bool ok1 = cv::imwrite(fileL.string(), rawL);
                bool ok2 = cv::imwrite(fileR.string(), rawR);
                if (ok1 && ok2)
                {
                    std::cout << "✅ 已保存原始分辨率帧: "
                              << leftW << "x" << leftH << ", 文件: " << fileL << "\n";
                }
                else
                    std::cerr << "⚠️ 保存失败\n";
            }
        }
        else if (key == 'q' || key == 27)
        {
            running = false;
            break;
        }
    }

    tL.join();
    tR.join();
    capLeft.release();
    capRight.release();
    cv::destroyAllWindows();
    return 0;
}
